using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using DS.SludgeEngine.Camera;
using DS.SludgeEngine.Base;
using DS.SludgeEngine.Base.GlobalContent;
using DS.SludgeEngine.Drawing;
using DS.SludgeEngine.Input;
using DS.SludgeEngine.Entities;
using DS.SludgeEngine.Particles;
using DS.SludgeEngine.Terrain;
using System.IO;

namespace DS.SludgeEngine.Engine
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Engine : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Engine()
        {


            graphics = new GraphicsDeviceManager(this);

            GameInformation.GraphicsManager = graphics;
            GameInformation.Game = this;




            // Activate the first screens.

        }


        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();
            // TODO: Add your initialization logic here
            //Content = new ContentManager(Services);

            GlobalContent.Manager = Content;
            GlobalContent.Manager.RootDirectory = "Content";
            GlobalContent.InitialiseContent("Content/ContentConfiguration.xml");
            this.IsMouseVisible = true;
            GlobalContent.LoadAll("Menu");
            Font1 = GlobalContent.Fonts["Font"];
            FontPos = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2,
    graphics.GraphicsDevice.Viewport.Height / 2);

            GlobalContent.PreLoadGroup("Main");

        }
        Vector2 FontPos;
        SpriteFont Font1;
        private void StartGame()
        {
            //GlobalContent.PreLoadGroup("Main");




            GameInformation.Game.Services.AddService(typeof(IInputControllerService), new InputController(InputConfiguration.Deserialise(File.ReadAllText("Content/InputConfiguration.xml"))));
            MouseController mouseController = new MouseController(GameInformation.Game);
            mouseController.DrawOrder = 2;
            GameInformation.Game.Components.Add(mouseController);
            GameInformation.Game.Services.AddService(typeof(IMouseController), mouseController);

            CameraManager cameraManager = new CameraManager(GameInformation.Game);
            cameraManager.Position = new Vector3(0.0f, 0.0f, 0.0f);
            cameraManager.LookAt(new Vector3());
            cameraManager.OrbitOffsetDistance = 50.0f;
            cameraManager.OrbitMaxZoom = 100.0f;
            cameraManager.OrbitMinZoom = 10.0f;
            cameraManager.MouseWheelSpeed = 10.0f;
            GameInformation.Game.Components.Add(cameraManager);
            GameInformation.Game.Services.AddService(typeof(ICameraComponent), cameraManager);
            cameraManager.Rotate(-110.0f, -60.0f, 0.0f);

            Ground terrain = new Ground(GameInformation.Game);
            terrain.DrawOrder = 0;
            GameInformation.Game.Components.Add(terrain);
            GameInformation.Game.Services.AddService(typeof(ITerrainComponent), terrain);

            base.Initialize();
            //ITerrainController terrain = (ITerrainController)GameInformation.Game.Services.GetService(typeof(ITerrainController));
            terrain.LoadTerrain(GlobalContent.Texture2Ds["Heightmap"]
                , GlobalContent.Texture2Ds["TreeMap"]);


        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {

            base.Update(gameTime);
            if (GameInformation.reset)
            {
                UnloadGame();

            }
        }

        private static void UnloadGame()
        {
            GameInformation.reset = false;
            while (GameInformation.Game.Components.Count > 1)
            {
                GameInformation.Game.Components.RemoveAt(1);
            }
            GameInformation.Game.Services.RemoveService(typeof(IInputControllerService));

            GameInformation.Game.Services.RemoveService(typeof(IDrawing3DManager));
            GameInformation.Game.Services.RemoveService(typeof(ICameraManager));


            GameInformation.Game.Services.RemoveService(typeof(IMouseController));
            GameInformation.Game.Services.RemoveService(typeof(ITerrainComponent));

            GameInformation.Game.Services.RemoveService(typeof(IDrawing2DManager));

            GameInformation.Game.Services.RemoveService(typeof(IParticleController));

            GameInformation.Game.Services.RemoveService(typeof(IEntityController));
            GlobalContent.UnloadGroup("Main");
        }
        bool loaded = false;
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            GraphicsDevice.RenderState.DepthBufferEnable = true;
            GraphicsDevice.RenderState.AlphaBlendEnable = false;
            GraphicsDevice.RenderState.AlphaTestEnable = false;
            if (!loaded)
            {
                GlobalContent.LoadAll("Main");
                StartGame();
                loaded = true;

            }
            base.Draw(gameTime);

        }
    }
}
